package com.cruel_wandering.wifi_geo_predictor.util;

import java.util.concurrent.Executor;

import com.cruel_wandering.wifi_geo_predictor.Logger;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;

/**
 * The class is a simple implementation of Timer, which knows to execute
 * Runnable-s at scheduled delays.
 * @author wmii
 *
 */
public class MyTimer
{
	private Context ctx;
	private Handler h;
	private Thread t = new Thread() {
		@Override
		public void run()
		{
			Looper.prepare();

			h = new Handler();

			Looper.loop();
		}
	};

	public MyTimer(Context ctx)
	{
		this.ctx = ctx;
		t.start();
	}

	/**
	 * Schedule a runnable for single execution after a specified delay.
	 * @param runnable the runnable to schedule
	 * @param delay the delay to wait before the execution
	 */
	public void schedule(Runnable runnable, long delay)
	{
		log("Scheduling <" + runnable + "> delayed in " + delay + "ms");
		h.postDelayed(runnable, delay);
	}

	private class LoopedRunnable implements Runnable
	{
		final Runnable r;
		final long p;

		public LoopedRunnable(Runnable runnable, long period)
		{
			this.r = runnable;
			this.p = period;
		}

		public void run()
		{
			log("Executing <" + r + ">");
			r.run();
			log("Scheduling <" + this + "> delayed in " + p + "ms");
			h.postDelayed(this, p);
		}
	}

	/**
	 * XXX: does not work!!!
	 * 
	 * Schedule a task for repeated fixed-delay execution after a specific delay.
	 * @param runnable the runnable to schedule
	 * @param delay the delay to wait before first execution
	 * @param period the period to wait between executions
	 */
	public void schedule(Runnable runnable, long delay, long period)
	{
		LoopedRunnable wrap = new LoopedRunnable(runnable, period);

		log("Scheduling <" + wrap + "> delayed in " + delay + "ms");
		h.postDelayed(wrap, delay);
	}

	/**
	 * Cancel a scheduled execution of a given runnable.
	 * @param runnable the scheduled runnable
	 */
	public void cancel(Runnable runnable)
	{
		log("Removing <" + runnable + ">");
		h.removeCallbacks(runnable);
	}

	private void log(String msg)
	{
		Logger.logAndToast(ctx, "MyTimer", msg);
	}
}